﻿using ProjScan.Modules;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

namespace ProjScan.Tools
{
    //
    // 摘要:
    //     帮助类 - Class167
    internal class ToolsHelper
    {
        public class Pair<T1, T2>
        {
            private T1 _item1;

            private T2 _item2;

            public Pair(T1 t1, T2 t2)
            {
                SetItem1(t1);
                SetItem2(t2);
            }

            public T1 GetItem1()
            {
                return _item1;
            }

            public void SetItem1(T1 t1)
            {
                _item1 = t1;
            }

            public T2 GetItem2()
            {
                return _item2;
            }

            public void SetItem2(T2 t2)
            {
                _item2 = t2;
            }
        }

        private static string m_ResultPath;

        //
        // 摘要:
        //     去除前后引号
        //
        // 参数:
        //   string_1:
        public static string TrimYH(string string_1)
        {
            char[] trimChars = new char[1]
            {
                '"'
            };
            return string_1.Trim(trimChars);
        }

        public static void GC()
        {
            System.GC.Collect();
            RenderTexture.active = null;
            EditorUtility.UnloadUnusedAssetsImmediate();
        }

        //
        // 摘要:
        //     获取结果输出目录 - smethod_30
        public static string GetScanOutPut()
        {
            if (string.IsNullOrEmpty(m_ResultPath))
            {
                m_ResultPath = Application.dataPath + "/../ScanOutPut";
            }

            try
            {
                if (!Directory.Exists(m_ResultPath))
                {
                    Directory.CreateDirectory(m_ResultPath);
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                throw ex;
            }

            return m_ResultPath;
        }

        //
        // 摘要:
        //     插件配置文件目录-ScanConfig
        public static string GetLocationPath()
        {
            string text = Path.Combine(Application.dataPath, Setting.BasePath);
            Directory.CreateDirectory(text);
            return text;
        }

        public static string GetProjectLocationPath()
        {
            string text = Path.Combine(Application.dataPath, Setting.ProjectBasePath);
            Directory.CreateDirectory(text);
            return text;
        }

        //
        // 摘要:
        //     获取结果目录
        public static string GetFailResultPath()
        {
            string text = Path.Combine(GetScanOutPut(), "Result/");
            if (!Directory.Exists(text))
            {
                Directory.CreateDirectory(text);
            }

            return text;
        }

        //
        // 摘要:
        //     获取单一规则详细信息目录
        public static string GetFailDetailPath()
        {
            string text = Path.Combine(GetScanOutPut(), "Detail/");
            if (!Directory.Exists(text))
            {
                Directory.CreateDirectory(text);
            }

            return text;
        }

        public static void ShowProgressBar(string Title, string Connet, float progress, bool IsHide = false)
        {
            if (!IsHide)
            {
                if (Singleton<ScanInfo>.Instance.isEditor)
                {
                    EditorUtility.DisplayProgressBar($" Scan [ {Title} ]", Connet, progress);
                }
            }
            else
            {
                EditorUtility.DisplayProgressBar($" Scan [ {Title} ]", Connet, progress);
            }
        }

        public static void DisplayDialog(string title, string message, string ok)
        {
            EditorUtility.DisplayDialog(title, message, ok);
        }

        public static void ClearProgressBar()
        {
            EditorUtility.ClearProgressBar();
        }

        //
        // 摘要:
        //     加上双引号
        //
        // 参数:
        //   str:
        public static string QuoteString(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }

            return "\"" + str + "\"";
        }

        //
        // 摘要:
        //     规范路径/
        //
        // 参数:
        //   dir:
        public static string DirConvert(string dir)
        {
            if (dir == null)
            {
                throw new Exception("DirConvert: param dir is null");
            }

            return dir.Replace("\\", "/");
        }

        //
        // 摘要:
        //     将一个文件的绝对路径转换为Unity项目中的相对路径。
        //
        // 参数:
        //   absolutePath:
        //     文件的绝对路径
        //
        // 返回结果:
        //     文件的相对路径
        public static string ConvertAbsolutePathToRelative(string absolutePath)
        {
            if (string.IsNullOrEmpty(absolutePath))
            {
                return null;
            }

            string result = null;
            if (absolutePath.StartsWith("Assets", StringComparison.OrdinalIgnoreCase))
            {
                return absolutePath;
            }

            if (absolutePath.StartsWith(Application.dataPath, StringComparison.OrdinalIgnoreCase))
            {
                if (absolutePath.Length == Application.dataPath.Length)
                {
                    result = "Assets";
                }
                else
                {
                    int length = Application.dataPath.Length;
                    if (absolutePath[length] != '/' && absolutePath[length] != '\\')
                    {
                        throw new Exception("Incorrect path: X:/../path/to/AssetsXXX");
                    }

                    result = "Assets" + absolutePath.Substring(length);
                }

                return result;
            }

            try
            {
                Uri uri = new Uri(absolutePath);
                Uri uri2 = new Uri(Application.dataPath + "/").MakeRelativeUri(uri);
                if (string.IsNullOrEmpty(uri2.ToString()))
                {
                    throw new Exception("Failed to get relative path");
                }

                result = "Assets/" + uri2.ToString();
            }
            catch (Exception ex)
            {
                Debug.LogError(absolutePath);
                ScanLog.Instance.LogInfo("AbsToAssetPath()", ((ex.GetType() == null) ? null : ex.GetType().ToString()) + "\n" + ex.Message + "\n" + ex.StackTrace);
            }

            return result;
        }

        //
        // 摘要:
        //     基于Asset的相对路径转换成绝对路径
        //
        // 参数:
        //   relativePath:
        public static string ConvertRelativePathToAbsolute(string relativePath)
        {
            if (relativePath == null)
            {
                return null;
            }

            relativePath = DirConvert(relativePath);
            if (!relativePath.StartsWith("Assets/") && relativePath != "Assets")
            {
                return null;
            }

            if (relativePath == "Assets/" || relativePath == "Assets")
            {
                return Application.dataPath;
            }

            return Application.dataPath + "/" + relativePath.Substring(7);
        }

        //
        // 摘要:
        //     检测parentDirPath是否包含childDirPath
        //
        // 参数:
        //   parentDirPath:
        //
        //   childDirPath:
        public static bool IsDirContain(string parentDirPath, string childDirPath)
        {
            if (parentDirPath == null || childDirPath == null)
            {
                return false;
            }

            parentDirPath = DirConvert(parentDirPath);
            childDirPath = DirConvert(childDirPath);
            if (!childDirPath.StartsWith(parentDirPath, StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }

            if (parentDirPath.Length + 2 >= childDirPath.Length)
            {
                return false;
            }

            try
            {
                return childDirPath[parentDirPath.Length] == '/';
            }
            catch (Exception)
            {
                Debug.LogError("IsDirContain:parentDirPath[" + parentDirPath + "] childDirPath[" + childDirPath + "]");
                return false;
            }
        }

        //
        // 摘要:
        //     路径是否匹配正则表达式
        //
        // 参数:
        //   pattern:
        //     正则表达式
        //
        //   input:
        //     路径
        public static bool IsMatch(string pattern, string input)
        {
            if (string.IsNullOrEmpty(pattern) || string.IsNullOrEmpty(input))
            {
                return false;
            }

            try
            {
                Regex regex = new Regex(pattern);
                return regex.IsMatch(input);
            }
            catch (Exception message)
            {
                Debug.LogError(message);
                return false;
            }
        }

        public static string GetGUID(UnityEngine.Object obj)
        {
            if (obj != null)
            {
                try
                {
                    return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(obj));
                }
                catch (Exception ex)
                {
                    Debug.LogError(ex.Message);
                }
            }

            return null;
        }

        internal static void SaveFile(string path, string content, bool needUtf8 = false)
        {
            CheckFileSavePath(path);
            try
            {
                if (needUtf8)
                {
                    UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
                    File.WriteAllText(path, content, encoding);
                }
                else
                {
                    File.WriteAllText(path, content, Encoding.Default);
                }
            }
            catch (IOException)
            {
                Debug.LogWarning("SaveError:[" + path + "]");
            }
        }

        internal static void CheckFileSavePath(string path)
        {
            string path2 = path;
            int num = path.LastIndexOf("/");
            if (num >= 0)
            {
                path2 = path.Substring(0, num);
            }
            else
            {
                num = path.LastIndexOf("\\");
                if (num >= 0)
                {
                    path2 = path.Substring(0, num);
                }
            }

            if (IsFileExists(path2))
            {
                DelFile(path2);
            }

            CheckDirection(path2);
        }

        //
        // 摘要:
        //     检查某个文件是否存在
        //
        // 参数:
        //   path:
        internal static bool IsFileExists(string path)
        {
            if (File.Exists(path))
            {
                return true;
            }

            return false;
        }

        internal static void DelFile(string path)
        {
            if (IsFileExists(path))
            {
                File.Delete(path);
            }
        }

        //
        // 摘要:
        //     检查某文件夹路径是否存在，如不存在，创建
        //
        // 参数:
        //   path:
        internal static void CheckDirection(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        //
        // 摘要:
        //     读取文件的字符串
        //
        // 参数:
        //   path:
        internal static string ReadFileText(string path, bool isUTF8 = false)
        {
            if (!File.Exists(path))
            {
                return "";
            }

            string text = "";
            return (!isUTF8) ? File.ReadAllText(path, Encoding.Default) : File.ReadAllText(path, Encoding.UTF8);
        }

        //
        // 摘要:
        //     检查一个 Color32 数组中的所有颜色是否与中央像素的颜色相同
        public static bool IsAllSameColorAsCenter(Color32[] colorArray, int width, int height)
        {
            int num = height / 2 * width + width / 2;
            Color32 color = colorArray[num];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int num2 = i * width + j;
                    Color32 color2 = colorArray[num2];
                    if (color2.r != color.r || color2.g != color.g || color2.b != color.b || color2.a != color.a)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public static Color32[] PixelArrayFromTexture2D(Texture2D inputTexture)
        {
            Color32[] array = null;
            Texture2D texture2D = ProcessTexture2D(inputTexture);
            if (texture2D != null)
            {
                array = texture2D.GetPixels32();
                UnityEngine.Object.DestroyImmediate(texture2D);
            }
            else
            {
                ScanLog.Instance.LogInfo(ScanLog.LogLevel.EXCEPTION, "Tex2D2ColorArray", "readableTex is null");
            }

            if (array == null || array.Length == 0)
            {
                ScanLog.Instance.LogInfo(ScanLog.LogLevel.EXCEPTION, "TextureRecord.Tex2D2ColorArray:", " readableTex.isReadable: " + texture2D.isReadable);
                throw new Exception("TextureRecord.Tex2D2ColorArray: colors is null or empty!");
            }

            return array;
        }

        private static Texture2D ProcessTexture2D(Texture2D inputTexture)
        {
            RenderTexture renderTexture = null;
            try
            {
                renderTexture = RenderTexture.GetTemporary(inputTexture.width, inputTexture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
            }
            catch (Exception ex)
            {
                ScanLog.Instance.LogInfo(inputTexture.name + "\n" + ex.Message + "\n" + ex.StackTrace);
                Debug.LogError(inputTexture.name + "\n" + ex.Message + "\n" + ex.StackTrace);
                throw;
            }

            Graphics.Blit(inputTexture, renderTexture);
            RenderTexture active = RenderTexture.active;
            RenderTexture.active = renderTexture;
            Texture2D texture2D = new Texture2D(inputTexture.width, inputTexture.height);
            texture2D.ReadPixels(new Rect(0f, 0f, renderTexture.width, renderTexture.height), 0, 0);
            texture2D.Apply();
            RenderTexture.active = active;
            RenderTexture.ReleaseTemporary(renderTexture);
            return texture2D;
        }

        public static float[] ConvertToFloatArray(string[] strings)
        {
            if (strings == null || strings.Length == 0)
            {
                return null;
            }

            float[] array = new float[strings.Length];
            for (int i = 0; i < strings.Length; i++)
            {
                array[i] = float.Parse(strings[i]);
            }

            return array;
        }

        public static string[] ConvertToStringArray(float[] floats)
        {
            if (floats == null || floats.Length == 0)
            {
                return null;
            }

            string[] array = new string[floats.Length];
            for (int i = 0; i < floats.Length; i++)
            {
                array[i] = floats[i].ToString();
            }

            return array;
        }

        public static Vector2 CalcSize(GUIStyle guistyle_0, string string_1)
        {
            return guistyle_0.CalcSize(new GUIContent(string_1));
        }

        public static string GetFullPathByName(string name)
        {
            string[] allAssetPaths = AssetDatabase.GetAllAssetPaths();
            for (int i = 0; i < allAssetPaths.Length; i++)
            {
                if (allAssetPaths[i].EndsWith(name))
                {
                    return allAssetPaths[i];
                }
            }

            return null;
        }

        public static string GetFullObjectPath(string initialPath, GameObject queriedObject)
        {
            GameObject gameObject = queriedObject.transform.root.gameObject;
            if (object.Equals(queriedObject, gameObject))
            {
                return initialPath;
            }

            GameObject gameObject2 = queriedObject;
            Stack<string> stack = new Stack<string>();
            do
            {
                stack.Push(gameObject2.name);
                gameObject2 = gameObject2.transform.parent.gameObject;
            }
            while (!object.Equals(gameObject2, gameObject));
            StringBuilder stringBuilder = new StringBuilder();
            while (stack.Count > 1)
            {
                stringBuilder.Append(stack.Pop()).Append("/");
            }

            stringBuilder.Append(stack.Pop());
            return stringBuilder.ToString();
        }

        public static void SelectionObject(string path, Module module)
        {
            UnityEngine.Object @object = null;
            try
            {
                switch (module)
                {
                    case Module.Basic_Assets_Fix:
                        {
                            string[] array3 = path.Split(new char[1]
                            {
                        '$'
                            });
                            if (array3.Length != 0)
                            {
                                @object = AssetDatabase.LoadMainAssetAtPath(array3[0]);
                            }

                            break;
                        }
                    case Module.Scenes_Fix:
                        {
                            string[] array2 = path.Split(new char[1]
                            {
                        '$'
                            });
                            string scenePath = array2[0];
                            string text = string.Empty;
                            if (array2.Length > 1)
                            {
                                text = array2[1];
                            }

                            EditorSceneManager.OpenScene(scenePath);
                            if (!string.IsNullOrEmpty(text))
                            {
                                @object = GameObject.Find(text);
                            }

                            break;
                        }
                    case Module.CS_Fix:
                        {
                            string assetPath = path.Split(new char[1]
                            {
                        ':'
                            })[0];
                            @object = AssetDatabase.LoadMainAssetAtPath(assetPath);
                            break;
                        }
                    case Module.Effects_Play_Fix:
                        @object = AssetDatabase.LoadMainAssetAtPath(path);
                        break;
                    case Module.Art_Assets_Fix:
                        {
                            string[] array = path.Split(new char[1]
                            {
                        '$'
                            });
                            @object = AssetDatabase.LoadMainAssetAtPath(array[0]);
                            break;
                        }
                    default:
                        @object = AssetDatabase.LoadMainAssetAtPath(path);
                        break;
                }
            }
            catch (Exception)
            {
                ScanLog.Instance.LogInfo("Ping Object Failed: " + path);
            }

            if (@object != null)
            {
                EditorGUIUtility.PingObject(@object);
                Selection.activeObject = @object;
            }
        }
    }
}